package plugin.bpce.Object;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;

import plugin.bpce.modelo.BPCEResult;
import plugin.bpce.modelo.ConfiguracaoModelo;
import plugin.bpce.modelo.DadosCoppeer;

public class InterfaceCoppeer {
	
	private HttpURLConnection conn;
	private String porta, pathConfiguracao;
	
	public InterfaceCoppeer(){
		porta = verificaPortaCOPPEER();
	}
	
	private InputStream conectaCOPPEER(Object parametro, String caminho, String porta, String metodo){
		URL url;
		ObjectOutputStream oos;		
		InputStream in;
		int temp;
		
		if (porta == null){
			temp = 0;
		}
		else if (porta.equalsIgnoreCase("")){
			temp = 0;
		}
		else{
			temp = Integer.parseInt(porta);
			temp += 2;			
		}
		
		porta = Integer.toString(temp);		
		
		try{
			url = new URL("http://localhost:" + porta + caminho);
			conn = (HttpURLConnection) url.openConnection();
			conn.disconnect();
			conn.setRequestMethod(metodo);
			conn.setRequestProperty("Content-Type", "application/octet-stream");			
			conn.setDoInput(true);
			conn.setDoOutput(true);
							
			oos = new ObjectOutputStream(conn.getOutputStream()); 
			oos.writeObject(parametro);
			oos.flush();
			
			conn.connect();			
			in = conn.getInputStream();			
			
			return in;
		}
		catch(Exception e){
			e.printStackTrace();
			
			return null;
		}		
	}
	
	public void salvaConfiguracao(Properties conf, String porta){
		String parametro;		
		
		if (conf != null)		
			parametro = propToString(conf);
		else
			parametro = "Tipo=3";		
		
		conectaCOPPEER(parametro, "/replicaConfiguracao.bp", porta, "POST");
		conn.disconnect();
	}

	public ConfiguracaoModelo recuperaConfiguracao(String porta) {
		InputStream in;
		ObjectInputStream input;
		ConfiguracaoModelo conf;
		
		in = conectaCOPPEER("", "/verificaConfiguracao.bp", porta, "GET");
		
		try{
			input = new ObjectInputStream(in);
			conf = (ConfiguracaoModelo) input.readObject();
			input.close();
			in.close();
		}
		catch(Exception e){
			e.printStackTrace();
			conf = null;
		}
		
		conn.disconnect();		
		return conf;
	}
	
	public DadosCoppeer getDadosCoppeer(){
		InputStream in;
		ObjectInputStream input;
		DadosCoppeer dados;
		
		in = conectaCOPPEER("", "/getDadosCoppeer.bp", porta, "GET");
		
		try{
			input = new ObjectInputStream(in);
			dados = (DadosCoppeer) input.readObject();
			input.close();
			in.close();
			
			dados.setPorta(porta);
		}
		catch(Exception e){
			e.printStackTrace();
			dados = null;
		}
		
		conn.disconnect();
		
		return dados;
	}
	
	public String verificaPortaCOPPEER() {
		String tmp, porta;
		String[] pastas;
		File pastaFeatures;		
		int i, j, v1, v2, v3, t1, t2, t3;
		Properties prop;
		FileInputStream fis;
		
		tmp = System.getProperty("user.dir");		
		tmp = tmp + "/features/";
		pastaFeatures = new File(tmp);		
		v1 = 0;
		v2 = 0;
		v3 = 0;
		
		if (pastaFeatures.isDirectory()){
			pastas = pastaFeatures.list();
			
			for(i = 0; i < pastas.length; i++){
				tmp = pastas[i];
				if (tmp.contains("plugin.bpce_")){
					j = tmp.indexOf("plugin.bpce_");
					tmp = tmp.substring(j + 12, tmp.length());
					
					j = tmp.indexOf(".");
					t1 = Integer.parseInt(tmp.substring(0, j));
					tmp = tmp.substring(j + 1, tmp.length());
					
					if (t1 > v1)
						v1 = t1;
					
					j = tmp.indexOf(".");
					t2 = Integer.parseInt(tmp.substring(0, j));
					tmp = tmp.substring(j + 1, tmp.length());
					
					if (t2 > v2)
						v2 = t2;
					
					t3 = Integer.parseInt(tmp);
					
					if (t3 > v3)
						v3 = t3;
				}
			}
		}
		
		pathConfiguracao = System.getProperty("user.dir") + "/features/plugin.bpce_" + Integer.toString(v1) + "." + Integer.toString(v2) + "." + Integer.toString(v3);
		
		try {
			prop = new Properties();
			fis = new FileInputStream(pathConfiguracao + "/config");
			prop.load(fis);		
			porta = prop.getProperty("Porta");
		} catch (Exception e) {
			porta = "";
		}
		
		return porta;
	}
	
	public void publicaModelo(Properties prop, String porta){
		String parametro;
		
		if (prop != null){		
			parametro = propToString(prop);
			
			conectaCOPPEER(parametro, "/publicaModelo.bp", porta, "POST");
			conn.disconnect();
		}
	}

	public void alteraPorta(String porta) {
		Properties prop;
		FileInputStream fis;
		FileOutputStream fos;
		
		try {
			prop = new Properties();
			fis = new FileInputStream(pathConfiguracao + "/config");
			fos = new FileOutputStream(pathConfiguracao + "/config");
			prop.load(fis);
			prop.setProperty("Porta", porta);
			prop.store(fos, "");
			
			this.porta = porta;
		} catch (Exception e) {
			porta = "";
		}		
	}
	
	public BPCEResult[] realizaBusca(String assunto){
		InputStream in;
		ObjectInputStream input;
		BPCEResult[] resultado;
		String parametro;
		Properties prop;
		
		prop = new Properties();
		prop.setProperty("assunto", assunto);
		
		parametro = "";
		
		if (prop != null)		
			parametro = propToString(prop);
		
		in = conectaCOPPEER(parametro, "/busca.bp", this.porta, "POST");
		
		try{
			input = new ObjectInputStream(in);
			resultado = (BPCEResult[]) input.readObject();
			input.close();
			in.close();
		}
		catch(Exception e){
			e.printStackTrace();
			resultado = null;
		}
		
		conn.disconnect();		
		return resultado;
	}
	
	private String propToString(Properties prop){
		String tmp;
		
		prop.setProperty("temp", "temp");
		
		tmp = prop.toString();
		tmp = tmp.substring(1, tmp.length() - 1);
		tmp = tmp.replace(", ", "&");
		
		return tmp;
	}

	public void pontuaVisualizacao(Properties prop) {
		String parametro;
		
		parametro = propToString(prop);
		conectaCOPPEER(parametro, "/pontuaVisualizacao.bp", porta, "POST");
		conn.disconnect();
	}
}
